/*
 * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
 * SPDX-License-Identifier: Unlicense OR CC0-1.0
 */

// 引入必要的头文件
#include "freertos/FreeRTOS.h" // FreeRTOS 核心功能
#include "freertos/task.h"     // 任务管理
#include "freertos/queue.h"    // 队列功能
#include "esp_log.h"           // ESP32 日志功能
#include "driver/rmt.h"
#include "ir_encoder.h"        // NEC 红外编码器
#include "ir_air_conditioner.h"
#include "ir_Midea.h"

static const char *TAG = "example"; // 日志标签
rmt_channel_handle_t tx_channel = NULL;
rmt_encoder_handle_t raw_encoder = NULL;

pAir_conditioner_t haier_acyrw02_init(void);
pAir_conditioner_t midea_r05d_init(void);

pAir_conditioner_t protocol_init(ir_protocol_t ir_protocol)
{
    switch (ir_protocol) {
        case HAIER_YRW02_PROTOCOL:
            return haier_acyrw02_init();
        case MIDEA_R05D_PROTOCOL:
            return midea_r05d_init();
        default:
            return NULL;
    }   
}
pAir_conditioner_t ir_air_conditioner_init(ir_protocol_t ir_protocol, uint8_t tx_gpio_num)
{
    if (ir_protocol >= IR_PROTOCOL_MAX)
        return NULL;

    // 配置RMT发送通道参数
    rmt_tx_channel_config_t tx_channel_cfg = {
        .clk_src = RMT_CLK_SRC_DEFAULT,            // 默认时钟源
        .resolution_hz = EXAMPLE_IR_RESOLUTION_HZ, // 分辨率1MHz
        .mem_block_symbols = 128,                  // 内存块大小（符号数）
        .trans_queue_depth = 4,                    // 发送队列深度
        .gpio_num = tx_gpio_num,                   // 发送引脚
    };
    ESP_ERROR_CHECK(rmt_new_tx_channel(&tx_channel_cfg, &tx_channel)); // 创建发送通道

    // 配置38KHz载波（红外常用频率）
    rmt_carrier_config_t carrier_cfg = {
        .duty_cycle = 0.33,    // 占空比1/3
        .frequency_hz = 38000, // 38KHz载波
    };
    ESP_ERROR_CHECK(rmt_apply_carrier(tx_channel, &carrier_cfg)); // 应用载波配置



    // 配置红外编码器
    ir_encoder_config_t raw_encoder_cfg = {
        .resolution = EXAMPLE_IR_RESOLUTION_HZ, // 与RMT分辨率一致
    };
    ESP_ERROR_CHECK(ir_encoder_new(&raw_encoder_cfg, &raw_encoder)); // 创建编码器

    ESP_ERROR_CHECK(rmt_enable(tx_channel)); // 使能发送通道

    //根据协议配置空调

    return protocol_init(ir_protocol);
}

/**
 * 设置空调温度
 * @param air_conditioner 空调设备实例指针
 * @param degrees 目标温度值（通常16-30℃）
 * @return ESP_OK成功，其他错误码失败
 */
esp_err_t air_conditioner_set_temp(pAir_conditioner_t air_conditioner, const uint8_t degrees)
{
    // 防御性检查
    if (air_conditioner == NULL) {
        return ESP_ERR_INVALID_ARG; // 无效参数
    }
    if (air_conditioner->set_temp == NULL) {
        return ESP_ERR_NOT_SUPPORTED; // 不支持该操作
    }
    // 温度范围验证（根据实际空调型号调整）
    if (degrees < 16 || degrees > 30) {
        return ESP_ERR_INVALID_ARG; // 温度超出范围
    }

    // 调用具体实现
    uint8_t result = air_conditioner->set_temp(air_conditioner, degrees);
    return (result == 0) ? ESP_OK : ESP_FAIL;
}

/**
 * 获取当前空调温度
 * @param air_conditioner 空调设备实例指针
 * @param degrees 输出参数，用于存储当前温度
 * @return ESP_OK成功，其他错误码失败
 */
esp_err_t air_conditioner_get_temp(pAir_conditioner_t air_conditioner, uint8_t *degrees)
{
    // 防御性检查
    if (air_conditioner == NULL || degrees == NULL) {
        return ESP_ERR_INVALID_ARG;
    }
    if (air_conditioner->get_temp == NULL) {
        return ESP_ERR_NOT_SUPPORTED;
    }

    // 获取当前温度
    *degrees = air_conditioner->get_temp(air_conditioner);
    // 验证温度合理性
    if (*degrees < 16 || *degrees > 30) {
        return ESP_ERR_INVALID_STATE; // 状态异常
    }
    return ESP_OK;
}

/**
 * 设置空调电源状态
 * @param air_conditioner 空调设备实例指针
 * @param on 电源状态（1:开启，0:关闭）
 * @return ESP_OK成功，其他错误码失败
 */
esp_err_t air_conditioner_set_power(pAir_conditioner_t air_conditioner, const uint8_t on)
{
    if (air_conditioner == NULL) {
        return ESP_ERR_INVALID_ARG;
    }
    if (air_conditioner->set_power == NULL) {
        return ESP_ERR_NOT_SUPPORTED;
    }
    // 验证电源状态参数
    if (on > 1) {
        return ESP_ERR_INVALID_ARG;
    }

    uint8_t result = air_conditioner->set_power(air_conditioner, on);
    return (result == 0) ? ESP_OK : ESP_FAIL;
}

/**
 * 获取空调电源状态
 * @param air_conditioner 空调设备实例指针
 * @param on 输出参数，存储电源状态（1:开启，0:关闭）
 * @return ESP_OK成功，其他错误码失败
 */
esp_err_t air_conditioner_get_power(pAir_conditioner_t air_conditioner, uint8_t *on)
{
    if (air_conditioner == NULL || on == NULL) {
        return ESP_ERR_INVALID_ARG;
    }
    if (air_conditioner->get_power == NULL) {
        return ESP_ERR_NOT_SUPPORTED;
    }

    *on = air_conditioner->get_power(air_conditioner);
    // 验证状态合理性
    if (*on > 1) {
        return ESP_ERR_INVALID_STATE;
    }
    return ESP_OK;
}

/**
 * 设置空调运行模式
 * @param air_conditioner 空调设备实例指针
 * @param mode 模式值（0:自动，1:制冷，2:制热，3:送风，4:除湿等）
 * @return ESP_OK成功，其他错误码失败
 */
esp_err_t air_conditioner_set_mode(pAir_conditioner_t air_conditioner, const uint8_t mode)
{
    if (air_conditioner == NULL) {
        return ESP_ERR_INVALID_ARG;
    }
    if (air_conditioner->set_mode == NULL) {
        return ESP_ERR_NOT_SUPPORTED;
    }
    // 验证模式参数（根据实际支持的模式调整范围）
    if (mode > 4) {
        return ESP_ERR_INVALID_ARG;
    }

    uint8_t result = air_conditioner->set_mode(air_conditioner, mode);
    return (result == 0) ? ESP_OK : ESP_FAIL;
}

/**
 * 获取空调当前运行模式
 * @param air_conditioner 空调设备实例指针
 * @param mode 输出参数，存储当前模式
 * @return ESP_OK成功，其他错误码失败
 */
esp_err_t air_conditioner_get_mode(pAir_conditioner_t air_conditioner, uint8_t *mode)
{
    if (air_conditioner == NULL || mode == NULL) {
        return ESP_ERR_INVALID_ARG;
    }
    if (air_conditioner->get_mode == NULL) {
        return ESP_ERR_NOT_SUPPORTED;
    }

    *mode = air_conditioner->get_mode(air_conditioner);
    if (*mode > 4) { // 与设置模式的范围对应
        return ESP_ERR_INVALID_STATE;
    }
    return ESP_OK;
}

/**
 * 设置空调风速
 * @param air_conditioner 空调设备实例指针
 * @param speed 风速等级（0:自动，1:低速，2:中速，3:高速等）
 * @return ESP_OK成功，其他错误码失败
 */
esp_err_t air_conditioner_set_fan(pAir_conditioner_t air_conditioner, const uint8_t speed)
{
    if (air_conditioner == NULL) {
        return ESP_ERR_INVALID_ARG;
    }
    if (air_conditioner->set_fan == NULL) {
        return ESP_ERR_NOT_SUPPORTED;
    }
    // 验证风速参数（根据实际支持的风速等级调整）
    if (speed > 3) {
        return ESP_ERR_INVALID_ARG;
    }

    uint8_t result = air_conditioner->set_fan(air_conditioner, speed);
    return (result == 0) ? ESP_OK : ESP_FAIL;
}

/**
 * 获取空调当前风速
 * @param air_conditioner 空调设备实例指针
 * @param speed 输出参数，存储当前风速等级
 * @return ESP_OK成功，其他错误码失败
 */
esp_err_t air_conditioner_get_fan(pAir_conditioner_t air_conditioner, uint8_t *speed)
{
    if (air_conditioner == NULL || speed == NULL) {
        return ESP_ERR_INVALID_ARG;
    }
    if (air_conditioner->get_fan == NULL) {
        return ESP_ERR_NOT_SUPPORTED;
    }

    *speed = air_conditioner->get_fan(air_conditioner);
    if (*speed > 3) { // 与设置风速的范围对应
        return ESP_ERR_INVALID_STATE;
    }
    return ESP_OK;
}

/**
 * 设置空调扩展功能
 * @param air_conditioner 空调设备实例指针
 * @param extend 扩展功能类型（自定义定义，如0:摆风，1:睡眠模式等）
 * @param data 功能参数（根据扩展功能类型定义）
 * @return ESP_OK成功，其他错误码失败
 */
esp_err_t air_conditioner_set_extend(pAir_conditioner_t air_conditioner,
                                     const uint8_t extend, uint8_t data)
{
    if (air_conditioner == NULL) {
        return ESP_ERR_INVALID_ARG;
    }
    if (air_conditioner->set_extend == NULL) {
        return ESP_ERR_NOT_SUPPORTED;
    }
    // 简单的扩展功能类型验证（根据实际需求调整）
    if (extend > 5) { // 假设支持0-5种扩展功能
        return ESP_ERR_INVALID_ARG;
    }

    uint8_t result = air_conditioner->set_extend(air_conditioner, extend, data);
    return (result == 0) ? ESP_OK : ESP_FAIL;
}

/**
 * 获取空调扩展功能状态
 * @param air_conditioner 空调设备实例指针
 * @param data 输出参数，存储扩展功能状态数据
 * @return ESP_OK成功，其他错误码失败
 */
esp_err_t air_conditioner_get_extend(pAir_conditioner_t air_conditioner, uint8_t *data)
{
    if (air_conditioner == NULL || data == NULL) {
        return ESP_ERR_INVALID_ARG;
    }
    if (air_conditioner->get_extend == NULL) {
        return ESP_ERR_NOT_SUPPORTED;
    }

    *data = air_conditioner->get_extend(air_conditioner);
    return ESP_OK;
}

/**
 * 发送空调控制指令
 * @param air_conditioner 空调设备实例指针
 * @return ESP_OK成功，其他错误码失败
 */
esp_err_t air_conditioner_send(pAir_conditioner_t air_conditioner)
{
    // 参数有效性检查
    if (air_conditioner == NULL) {
        return ESP_ERR_INVALID_ARG;
    }
    if (air_conditioner->send == NULL) {
        return ESP_ERR_NOT_SUPPORTED;
    }

    if (raw_encoder == NULL) {
        return ESP_ERR_INVALID_STATE; // 编码器未初始化
    }

    size_t symbol_num = 0;
    rmt_symbol_word_t *out_symbols = air_conditioner->send(air_conditioner, &symbol_num);

    // 检查编码结果
    if (out_symbols == NULL || symbol_num == 0) {
        return ESP_FAIL; // 编码失败
    }

    // 发送配置
    rmt_transmit_config_t transmit_cfg = {
        .loop_count = 0, // 不循环发送
    };

    // 发送时序数据
    esp_err_t ret = rmt_transmit(tx_channel, raw_encoder, out_symbols, symbol_num, &transmit_cfg);
    if (ret != ESP_OK) {
        ESP_LOGE(TAG, "rmt_transmit failed, ret=%d", ret);
        //free(out_symbols); // 发送失败释放资源
        return ret;
    }
    // 等待发送完成
    rmt_tx_wait_all_done(tx_channel, -1);

    return ESP_OK;
}

/**
 * 释放空调控制相关资源
 * @param air_conditioner 空调设备实例指针
 * @return ESP_OK成功，其他错误码失败
 */
esp_err_t air_conditioner_del(pAir_conditioner_t air_conditioner)
{
    // 避免重复释放
    if (air_conditioner == NULL) {
        return ESP_OK;
    }

    // 释放RMT资源

        rmt_disable(tx_channel);
        rmt_del_channel(tx_channel);
        tx_channel = RMT_CHANNEL_MAX; // 标记为无效通道

    // 释放编码器
    if (raw_encoder != NULL) {
        raw_encoder->del(raw_encoder);
        raw_encoder = NULL;
    }

    // 释放空调实例资源
    if (air_conditioner->del != NULL) {
        air_conditioner->del(air_conditioner);
    } else {
        // 如果没有自定义释放函数，直接释放内存
        free(air_conditioner);
    }

    return ESP_OK;
}
